#	This file is part of Metriflot.
#
#    Metriflot is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    Metriflot is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with Metriflot.  If not, see <http://www.gnu.org/licenses/>.
#
#	 Copyright 2011 David Irvine
# 

import time
import datetime
from django.db import models


class Metric(models.Model):
	"""The Metric class represents a stored metric in the system, every time
	a machine or process reports data it is stored as a metric object in the
	database.
	"""
	
	system=models.CharField(
			max_length=128,
			help_text="""Stores the identifier of the system that generated the
					     metric, this could be the hostname of a system, or the 
					     name of an application, it is completely freeform.""",
			)

	series=models.CharField(
			max_length=128,
			help_text="""The name of the data series, use this to give each data
					   series a unique name.  Use this name to include the
					   series within a report.""",
			)

	value=models.FloatField(
			help_text="""The actual value of the series for this system at this 
					   time, it must be a numeric value.""",
			)
	ts=models.DateTimeField(
			help_text="""The datetime object representing the time the metric was
					   valid""",
			)

	def chartArray(self):
		"""Returns an array containing two elements, the date in milliseconds
		   since the javascript epoch, and the value at that time.  This is 
		   used to generate the series data for the graph."""
		return [
				self.jsDate(),
				self.value
			]

	def jsDate(self):
		"""Returns the number of milliseconds since the epoch."""
		return int(1000*time.mktime(self.ts.timetuple()))

	def __unicode__(self):
		return self.series


class Graph(models.Model):
	"""Graphs are combined into reports, each graph has one or more series
	attached to it."""

	name=models.CharField(
			max_length=128,
			help_text="The name for the graph, this is displayed in the report",
			)
	
	description=models.TextField(
			max_length=128,
			help_text="""Describe the purpose of the graph, this is displayed in 
					   the report above the graph image""",
					)

	def __unicode__(self):
		return self.name
		
class GraphOptions(models.Model):
	"""Global graph options, these are passed directly to flot when rendering"""

	graph=models.ForeignKey(
			'Graph',
			related_name='options', 
			help_text="The graph that this option is connected to",
			)

	name=models.CharField(
			max_length=128,
			help_text="""Name of the options, options are passed directly to 
					   flot.""",
					)

	value=models.CharField(
			max_length=128,
			help_text="""Value for the option, this is sent directly to flot, it
					   is possible to enter json data if required.""",
					)

	def __unicode__(self):
		return self.name

class GraphSeries(models.Model):
	"""Series that are attached to each graph"""
	graph = models.ForeignKey('Graph', related_name='series')
	name=models.CharField(
			max_length=128,
			help_text="Enter the name of the series to use",
			)
	def __unicode__(self):
		return self.name

class GraphSeriesOptions(models.Model):
	"""Options for each series, these are passed directly to flot when 
	   rendering"""
	series=models.ForeignKey('GraphSeries', related_name='options')
	name=models.CharField(
			max_length=128,
			help_text="""Name of the options, options are passed directly to 
					   flot.""",
					   )
	value=models.CharField(
			max_length=128,
			help_text="""Value for the option, this is sent directly to flot, it
					   is possible to enter json data if required.""",
					   )

	def __unicode__(self):
		return self.name


class Report(models.Model):
	"""Reports contain one or more graphs"""
	name=models.CharField(
			max_length=128,
			help_text="""Give your report a meaningful name, it will be displayed
					   in the report.""",
			)
	description=models.TextField(
			max_length=128,
			help_text="""Enter a description for the report, it will be displayed
					   in the report""",
			)
	graphs=models.ManyToManyField(
			Graph, 
			related_name='reports',
			help_text='Select graphs that shall be displayed in the report',
			)

